/*--------------------------------------------------------------------------------------------------
Yatak Operation System Project Copyright 2012-2013
Author : Ilya Churaev
Started : 3 Feb 2013		Updated : 6 Mar 2013
File Name : users.h			Purpose : Declarations for obtaining system time
--------------------------------------------------------------------------------------------------*/
#include <yatak/debug.h>
#include <yatak/yatak.h>
#include <yatak/mutex.h>
#include <string.h>
#include <users.h>
#include <sched.h>

extern uid_t uid_u;
//running task
extern volatile task_t *current_task;

//linked list
extern volatile task_t *ready_queue;

static task_t * find_user (task_t * task, char * name)
{
	int ret = 0;
	if (task->brother)
		ret = find_user (task->brother, name);
	if (ret)
		return ret;
	if (task->child)
		ret = find_user (task->child,name);
	if (ret)
		return ret;
	if (!strcmp(task->name, name) && task->uid == task->pid)
		return task;
	return 0;
}

task_t * find_current_user ()
{
	task_t *tmp = (task_t *)ready_queue;
	while (tmp->parent) tmp = tmp->parent;
	return find_user (tmp, whoami());
}

void logout ()
{
	// Могу добавить выполнение завершающего скрипта
	static mutex_t mutex;
	//uint32 flags;
	pid_t pid;
	
	mutex_enter (&mutex);
	//save_flags (flags);
	//cli();
	task_t * user = find_current_user ();
	task_t * ret_task = get_return_point ();
	if (!user)
	{
		dprintf ("[logout] Cannot be found current user...\n");
		
		mutex_leave (&mutex);
		//restore_flags (flags);
		return;
	}
	if (!ret_task)
	{
		dprintf ("[logout] Cannot be found return point...\n");
		
		mutex_leave (&mutex);
		//restore_flags (flags);
		return;
	}
	pid = user->pid;
	current_task = ready_queue = ret_task;
	task_t * tmp = (task_t *)ready_queue;
	while (tmp->next)
	{
		if (tmp->next == user)
			break;
		tmp = tmp->next;
	}
	if (kill_task(pid))
	{
		dprintf ("[logout] Kill user...Fail\n");
	}
	else
	{
		dprintf ("[logout] Kill user...OK\n");
	}
	if (tmp)
		tmp->next = NULL;
	uid_u = 0;
	
	mutex_leave (&mutex);
	//restore_flags (flags);
	switch_task();
}
